import os
import sys

from PyQt5.QtCore import *
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtWidgets import *
from pydub import AudioSegment, silence

from ui.mainForm import Ui_MainForm

project_path = os.getcwd()


class MainForm(QtWidgets.QWidget):
    #  通过类成员对象定义信号对象
    _startThread = pyqtSignal()

    def __init__(self):
        super(MainForm, self).__init__()
        self.ui = Ui_MainForm()
        self.ui.setupUi(self)

    def log(self, data):
        self.ui.logEdit.append(data)

    def choice_button_click(self):
        fileLists, _ = QtWidgets.QFileDialog.getOpenFileNames(None, "文件选择", project_path, "All Files(*);;WaveFiles(*.wav)")
        self.ui.listWidget.addItems(fileLists)

    def ok_button_click(self):
        min_length = self.ui.spinBox.value()         # 截取出的音频长度不会低于这个值，单位：ms
        min_silence_len = self.ui.spinBox_2.value()  # 当语音间隔长度大于这个值时进行一次截断，单位：ms
        min_to_cut = self.ui.spinBox_3.value()       # 如果原音频短于这个长度则不会被切割，单位：ms
        paths = []
        for i in range(self.ui.listWidget.count()):
            paths.append(self.ui.listWidget.item(i).text())

        wav_output = project_path + "/wav/output/"
        if not os.path.exists(wav_output):
            os.makedirs(wav_output)

        self.exec(paths, wav_output, min_length, min_silence_len, min_to_cut)

    def exec(self, paths, wav_output, min_length, min_silence_len, min_to_cut):
        for wav_path in paths:
            try:
                self.fileCut(wav_path, wav_output, min_length, min_silence_len, min_to_cut)
            except Exception as e:
                self.log(e.args)


    def fileCut(self, wav_path, wav_output, min_length, min_silence_len, min_to_cut):
        wav_name = wav_path.split("/")[-1:][0].split(".")[0]  # 从路径中截取出不带后缀的文件名
        sound = AudioSegment.from_wav(wav_path)

        if sound.duration_seconds * 1000 < min_to_cut:
            sound.export(wav_output + wav_name + ".wav", format="wav")
            self.log(f"原音频短于最小长度{wav_path}")
            return

        sound_cut_list = silence.split_on_silence(sound, min_silence_len=min_silence_len, silence_thresh=-50,
                                                  keep_silence=200)
        self.log(f"读取文件{wav_path} 截取到[{len(sound_cut_list)}]个！")
        QApplication.processEvents()

        cut_file = AudioSegment.silent(1)  # 占位
        cut_file_backup = AudioSegment.silent(1)  # 保存最后被写入文件的声音文本，以防出现在最后切出一段很短的音频，如果出现这种情况，将其合入前一个音频文件
        i = 0
        for sound_cut in sound_cut_list:
            if cut_file.duration_seconds <= 0.001:
                cut_file = sound_cut
            else:
                cut_file = cut_file + AudioSegment.silent(min_silence_len) + sound_cut
            QApplication.processEvents()

            if cut_file.duration_seconds * 1000 > min_length:  # 检查如果截取到的音频过短，则将其累积到下一条
                # print("---------")
                # print(sound_cut.duration_seconds)
                # print(cut_file.duration_seconds)
                tmp_file = wav_output + wav_name + "_" + str(i) + ".wav"
                cut_file.export(tmp_file, format="wav")
                cut_file_backup = cut_file

                self.log(f"写入文件为:  {tmp_file} ")
                self.log(f"写入！为：{cut_file.duration_seconds}秒, 此时备份长度为：{cut_file_backup.duration_seconds}秒")
                i = i + 1
                cut_file = AudioSegment.silent(1)
            else:
                self.log(f"过短！为：{cut_file.duration_seconds}秒,累计")

        if cut_file.duration_seconds >= 0.001:
            self.log(f"需要覆盖，备份的长度为：{cut_file_backup.duration_seconds}秒")
            cut_file = cut_file_backup + AudioSegment.silent(min_silence_len) + cut_file
            cut_file.export(wav_output + wav_name + "_" + str(i - 1) + ".wav", format="wav")
            self.log(f"加长后覆盖上一条！为：{cut_file.duration_seconds}秒")

        self.log(f"截取出{i}个音频文件 \n")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = MainForm()
    main.show()
    sys.exit(app.exec_())
